#ifndef _PRIMITIVE_HPP_
#define _PRIMITIVE_HPP_

#include <cmath>


#include "vector.hpp"
#include "color.hpp"
#include "ray.hpp"
#include "config.hpp"

class Primitive
{
private:
    real_t precision;
    real_t scene_size;
    
    
public:
    Material    material;
    
    virtual bool Intersection       ( Ray &ray, Vector &hit_point, Vector &normal ) {return false;}
    virtual bool IntersectionInner  ( Ray &ray, Vector &hit_point, Vector &normal ) {return false;}
    
    virtual bool IsIntersected ( Ray &ray) { return false;}
    ///////
    Primitive() {} ;
    ~Primitive(){};
};

class PrimSphere : public Primitive
{
public:
    Vector      _position;
    real_t     _radius;
    
    virtual bool Intersection       ( Ray &ray, Vector &hit_point, Vector &normal );
    virtual bool IntersectionInner  ( Ray &ray, Vector &hit_point, Vector &normal );
    
    virtual bool IsIntersected ( Ray &ray);
    
    void SetPosition  ( Vector &position );
    void SetRadius    ( real_t radius );
    ///////
    PrimSphere();
    ~PrimSphere();
};

class PrimTriangle : public Primitive
{
private:
    Vector      _p1, _p2, _p3;
    
    Vector      _normal;
    real_t     _D;
    real_t     _S;
public:

    virtual bool Intersection       ( Ray &ray, Vector &hit_point, Vector &normal );
    virtual bool IntersectionInner  ( Ray &ray, Vector &hit_point, Vector &normal );
    
    virtual bool IsIntersected ( Ray &ray);
    
    void SetPoints    ( Vector & p1, Vector & p2, Vector & p3 );
    ///////
    PrimTriangle();
    ~PrimTriangle();
};

class PrimTor : public Primitive
{
private:
    Vector      _position;
    Vector      _normal;
    real_t      _radius_inner, _radius_outer;
    
public:
    
    virtual bool Intersection       ( Ray &ray, Vector &hit_point, Vector &normal );
    virtual bool IntersectionInner  ( Ray &ray, Vector &hit_point, Vector &normal );
    
    virtual bool IsIntersected ( Ray &ray);
    
    void SetPosition( Vector & position);
    void SetNormal  ( Vector & normal);
    void SetRadius  ( real_t inner, real_t outer);
    ///////
    PrimTor();
    ~PrimTor();
    real_t olo;
};

/////////////
#endif //_PRIMITIVE_HPP_
